/*e4.l*/
%option main
%option yywrap
%{
    #include <stdio.h>
    #include <string.h>
    int Row=1;
    char *Ans = "";
    int leftBigBracketNums = 0;
    int rightBigBracketNums = 0;
%}
KeyWord("main"|"double"|"return"|"float"|"if"|"else"|"do"|"while"|"for"|"scanf"|"printf"|"char"|"sqrt"|"abs"|"float")
KeyWord2 ("for"|"while"|"if")[(]
OPT ("+"|"-"|"%"|"*"|"/"|"+="|"-="|"*="|"/="|">"|"<"|"<="|">="|"=="|"="|"&"|"\|"|"!"|"<<"|">>")
Identify ({Letter}|_)({Letter}|_|{Digit})*
Function ({Letter}|_)({Letter}|_|{Digit})*[(]
Digit [0-9]
UnsignedInteger [1-9]{Digit}*
Integer ("+"|"-")?{Digit}+("e"(("+"|"-"){UnsignedInteger})?)?
Decimal {Integer}.{Digit}+
Float {Integer}.{Digit}+("e"(("+"|"-"){UnsignedInteger})?)?
Letter [a-zA-Z]
Comment ("/*"|"*").*
Type ("int"|"double"|"short"|"char"|"void"|"long")
Bracket ("["|"]"|";"|","|"\"")
LeftBigBracket ("{")
RightBigBracket ("}")
LeftSmallBracket ("(")
RightSmallBracket (")")
RightSmallBracket (")")
Typeidentity ("%"|"&")[a-z]
Next("\n")
%%

"main" {
    if (leftBigBracketNums == 0) {
            char* function = strncpy(function, yytext, strlen(yytext) - 2);
            AddOutput(Row, "main:", function);
    } else {
            AddOutput(Row, "    callee:", yytext);
    }
}
{Type} {}
{KeyWord} {}
{KeyWord2} {}
{OPT} {}
{Identify} {}
{Function} {
    if (leftBigBracketNums == 0) {
        char* function = yytext;
        AddOutput(Row, "caller:",function);
    } else {
        AddOutput(Row, "    callee:", yytext);
    }
}
{Integer} {}
{Decimal} {}
{Float} {
    char *p = strchr(yytext, 'e');
    if (p && yytext[strlen(yytext)-1] == 'e'){
        printf("Error at Line %d: Illegal floating point number \"%s\".\n",Row,yytext);
        return;
    } else {
    }
}
{Next} {++Row;}
{Typeidentity} {}

{Bracket} {}

{LeftBigBracket} {
    leftBigBracketNums++;
}
{RightBigBracket} {
    if (leftBigBracketNums <= 0) {
        printf("BracketError");
    } else {
        leftBigBracketNums--;
    }
}
{Comment} {}
. {}
%%
int yywrap()
{
    printf("%s", Ans);
    return 1;
}
void AddOutput(int Row, char* type, char* text){
    char str[50];
    sprintf(str, "line%-3d: %s %s)\n", Row, type, text);
    char *tmp = Ans;
    Ans = (char *) malloc(strlen(tmp) + strlen(str) + 1);
    sprintf(Ans, "%s%s", tmp, str);
    if(strlen(tmp) > 0)
        free(tmp);
    return ;
}